package com.demo2do.sms.handler.impl;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.ons.api.SendResult;
import com.aliyun.openservices.ons.api.exception.ONSClientException;
import com.demo2do.core.entity.result.Result;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.sms.Constant;
import com.demo2do.sms.entity.sms.SmsCompany;
import com.demo2do.sms.entity.sms.SmsRecord;
import com.demo2do.sms.handler.SmsSender;
import com.demo2do.sms.service.SmsService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 
 * @author mohanlan
 *
 */
//@Component("smsSender")
public class SmsQueueSenderImpl implements SmsSender {
    
    private static final Logger logger = LoggerFactory.getLogger(SmsQueueSenderImpl.class);
    
    @Value("#{ons['topic.sms']}")
    private String smsTopic;
    
    @Autowired
    private Producer messageProducer;
    
    @Autowired
    private SmsService smsService;
    
    /*
     * (non-Javadoc)
     * @see com.demo2do.sms.handler.SmsSender#send(java.lang.String, java.lang.String, java.lang.String)
     */
    public Result send(String client, String mobiles, String message) {
        
        Result result = new Result();
        
        // 1. validate client in local database
        SmsCompany smsCompany = smsService.loadCompany(client);
        
        if(smsCompany == null || StringUtils.isEmpty(smsCompany.getApikey())) {
            logger.error("#send() get not valida sms company (not exit or empty apikey) with params client[{}] mobiles[{}] message[{}]", client, mobiles, message);
            return result.fail("400").message("请求参数错误！");
        }
        
        // 2. call remote api to send sms ( dispatch different api url )
        String[] mobilesArray = StringUtils.split(mobiles, ",");
        List<String> mobileList = Arrays.asList(mobilesArray);
        
        if(CollectionUtils.isNotEmpty(mobileList) && mobileList.size() == 1) {
            
            SmsRecord smsRecord = new SmsRecord(mobiles, message, client);
            smsService.create(smsRecord.initialize());
            
            result = this.sendToQueue(mobiles, message, smsCompany.getApikey(), false);
            
        }else if(CollectionUtils.isNotEmpty(mobileList) && mobileList.size() > 1) {
            
            List<SmsRecord> smsRecords = new ArrayList<SmsRecord>();
            for(String mobile :mobileList) {
                SmsRecord smsRecord = new SmsRecord(mobile, message, client);
                smsRecords.add(smsRecord.initialize());
            }
            
            smsService.create(smsRecords);
            
            result = this.sendToQueue(mobiles, message, smsCompany.getApikey(), true);
        }
        
        return result;
    }
    
    /**
     * 
     */
    protected Result sendToQueue(String mobiles, String content, String apikey, boolean batch) {

        Result result = new Result();
        
        try {
            
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("mobile", mobiles);
            params.put("text", content);
            params.put("apikey", apikey);
            
            String json = new ObjectMapper().writeValueAsString(params);
            
            if (batch) {
                
                Message onsMessage = new Message(smsTopic, Constant.BATCH_SMS_TAG, json.getBytes(StandardCharsets.UTF_8));
                String mssageKey = String.valueOf(new Date().getTime());
                onsMessage.setKey(mssageKey);
                
                SendResult sendResult = messageProducer.send(onsMessage);
                assert sendResult != null;
                
                logger.info("#send() batch send message[{}] to mq success, with topic[zhongtouwan-test], tag[{}] and return sendResult", onsMessage, Constant.BATCH_SMS_TAG, JsonUtils.toJson(sendResult));
                
            } else {
                
                Message onsMessage = new Message(smsTopic, Constant.SINGLE_SMS_TAG, json.getBytes(StandardCharsets.UTF_8));
                String mssageKey = String.valueOf(new Date().getTime());
                onsMessage.setKey(mssageKey);
                
                SendResult sendResult = messageProducer.send(onsMessage);
                assert sendResult != null;
                
                logger.info("#send() single send message[{}] to mq success, with topic[zhongtouwan-test], tag[{}] and return sendResult", onsMessage, Constant.SINGLE_SMS_TAG, JsonUtils.toJson(sendResult));
            }
            
            result.success().message("发送短信成功进入队列");
            
        }catch (ONSClientException | JsonProcessingException e) {
            
            logger.error("#send() send message failed! occurs error:", e);
            result.fail("500").message("发送短信进入队列失败");
        }
        
        return result;
    }
}
